﻿using System;

using Microsoft.StyleCop.CSharp;

namespace StyleCopContrib.CSharp.Rules
{
	internal class NamingRules
	{
		private const string _PropertyForPrivateFieldUnderscorePrefix = "PrivateFieldUnderscorePrefix";
		private const string _PropertyForPrivateFieldCasing = "PrivateFieldCasing";


		internal static bool CheckPrivateFieldUnderscorePrefix(CsElement element,
			CsElement parentElement,
			DocumentAnalyzer context)
		{
			var field = (Field)element;
			if (field.AccessModifier != AccessModifierType.Private)
			{
				return true;
			}

			var underscoreRequired = context.GetProperty<bool>(
				element.Document, _PropertyForPrivateFieldUnderscorePrefix);
			var underscoreExists = field.Declaration.Name.StartsWith("_");

			if ((underscoreRequired && !underscoreExists) ||
				(!underscoreRequired && underscoreExists))
			{
				context.AddViolation(
					field,
					field.LineNumber,
					RuleNames.MemberNameUnderscorePrefix,
					field.Declaration.Name);
			}
			return true;
		}

		internal static bool CheckPrivateFieldCasing(CsElement element,
			CsElement parentElement,
			DocumentAnalyzer context)
		{
			var field = (Field)element;
			if (field.AccessModifier != AccessModifierType.Private)
			{
				return true;
			}

			var requiredCasing = context.GetEnumProperty<CasingOptions>(
				element.Document, _PropertyForPrivateFieldCasing);
			var unprefixedName = field.Declaration.Name.TrimStart('_');
			var violated = false;

			if (requiredCasing == CasingOptions.CamelCase &&
				char.IsUpper(unprefixedName[0]))
			{
				violated = true;
			}
			else if (requiredCasing == CasingOptions.PascalCase &&
				char.IsLower(unprefixedName[0]))
			{
				violated = true;
			}

			if (violated)
			{
				context.AddViolation(
					field,
					field.LineNumber,
					RuleNames.MemberNameCasing,
					field.Declaration.Name,
					Convert.ToString(requiredCasing));
			}
			return true;
		}
	}
}
